package top.xierongsheng.code;

import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingRequestHeaderException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import jakarta.xml.bind.ValidationException;

import java.util.Objects;


/**
 * 全局异常处理器(控制层)
 *
 * @auther 谢荣生
 * @datetime 2020/10/27 16:10
 */
@Slf4j
@RestControllerAdvice
public class GlobalControllerExceptionHandler {
    /**
     * 方法参数无效异常
     *
     * @auther 谢荣生
     * @datetime 2020/11/19 14:52
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        return R.fail(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }

    /**
     * 数据转换失败异常
     *
     * @auther 谢荣生
     * @datetime 2020/11/19 14:52
     */
    @ExceptionHandler(ConversionFailedException.class)
    public R handleConversion(RuntimeException ex) {
        return R.fail(ex.getMessage());
    }


    /**
     * 验证异常
     *
     * @param e
     * @return
     * @auther 谢荣生
     * @datetime 2020/11/19 14:52
     */
    @ExceptionHandler(ValidationException.class)
    public R handleValidationException(ValidationException e) {
        return R.fail(e.getCause().getMessage());
    }

    /**
     * 约束冲突异常
     *
     * @param e
     * @return
     * @auther 谢荣生
     * @datetime 2020/11/19 14:53
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public R handleConstraintViolationException(ConstraintViolationException e) {
        return R.fail(e.getMessage());
    }

    /**
     * 路径错误异常
     *
     * @param e
     * @return
     * @auther 谢荣生
     * @datetime 2020/11/19 14:54
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    public R handlerNoFoundException(Exception e) {
        return R.fail("路径不存在，请检查路径是否正确");
    }

    /**
     * 重复密钥异常
     *
     * @param e
     * @return
     * @auther 谢荣生
     * @datetime 2020/11/19 14:55
     */
    @ExceptionHandler(DuplicateKeyException.class)
    public R handleDuplicateKeyException(DuplicateKeyException e) {
        return R.fail("触发数据库唯一性约束，请检查后提交");
    }

    /**
     * 空指针异常
     *
     * @param e
     * @return
     * @auther 谢荣生
     * @datetime 2020/11/20 15:49
     */
    @ExceptionHandler(NullPointerException.class)
    public R handleNullPointerException(NullPointerException e) {
        return R.error("空指针异常，请检查传输数据");
    }

    /**
     * 缺少请求头异常
     *
     * @param e
     * @return
     * @auther 谢荣生
     * @datetime 2020/11/24 10:36
     */
    @ExceptionHandler(MissingRequestHeaderException.class)
    public R handleMissingRequestHeaderException(MissingRequestHeaderException e) {
        return R.fail(e.getMessage());
    }

    /**
     * Http消息不可读异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public R handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        return R.fail("缺少必要的请求正文");
    }


    /**
     * 其他异常
     *
     * @param e
     * @return
     * @auther 谢荣生
     * @datetime 2020/11/19 14:55
     */
    @ExceptionHandler(Exception.class)
    public R handleException(Exception e) {
        return R.error(e.getMessage());
    }

}
